{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "ef0a4ee4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'C:\\\\Users\\\\oscar'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%pwd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "japanese-margin",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'C:\\\\Users\\\\oscar'"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os\n",
    "os.getcwd()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "executive-insulin",
   "metadata": {},
   "outputs": [],
   "source": [
    "os.chdir('C:\\\\Users\\\\oscar\\\\Documents\\\\Modelos+Marina')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "0888b480",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'C:\\\\Users\\\\oscar\\\\Documents\\\\Modelos+Marina'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%pwd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d29220ca",
   "metadata": {},
   "outputs": [],
   "source": [
    "from tensorflow import keras\n",
    "#keras.__version__\n",
    "import os, shutil"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "d979c4e9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "C:\\Users\\oscar\\Documents\\Modelos+Marina\n",
      "C:\\Users\\oscar\\Documents\\Modelos+Marina\\conv2\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "#create a folder named \"conv2\" in directory\n",
    "original_dir = os.path.abspath('C:\\\\Users\\\\oscar\\\\Documents\\\\Modelos+Marina')\n",
    "# The directory where we will\n",
    "# store our smaller dataset\n",
    "base_dir = os.path.join(original_dir, \"conv2\")\n",
    "print(original_dir)\n",
    "print(base_dir)\n",
    "# added by reviewer\n",
    "isdir = os.path.isdir(base_dir) \n",
    "print(isdir) \n",
    "\n",
    "if isdir ==True:\n",
    "    shutil.rmtree(base_dir)\n",
    "\n",
    "os.mkdir(base_dir)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "6b486b83",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Directories for our training,\n",
    "# validation and test splits\n",
    "train_dir = os.path.join(base_dir, 'train')\n",
    "os.mkdir(train_dir)\n",
    "validation_dir = os.path.join(base_dir, 'validation')\n",
    "os.mkdir(validation_dir)\n",
    "\n",
    "\n",
    "\n",
    "# Directory with our training leopard pictures\n",
    "train_leop_dir = os.path.join(train_dir, 'LPZP')\n",
    "os.mkdir(train_leop_dir)\n",
    "\n",
    "# Directory with our training hyena pictures\n",
    "train_hyena_dir = os.path.join(train_dir, 'HESP')\n",
    "os.mkdir(train_hyena_dir)\n",
    "\n",
    "# Directory with our training wolf pictures\n",
    "train_wolf_dir = os.path.join(train_dir, 'WP')\n",
    "os.mkdir(train_wolf_dir)\n",
    "\n",
    "\n",
    "\n",
    "# Directory with our validation leopard pictures\n",
    "validation_leop_dir = os.path.join(validation_dir, 'LPZP')\n",
    "os.mkdir(validation_leop_dir)\n",
    "\n",
    "# Directory with our validation hyena pictures\n",
    "validation_hyena_dir = os.path.join(validation_dir, 'HESP')\n",
    "os.mkdir(validation_hyena_dir)\n",
    "\n",
    "# Directory with our validation wolf pictures\n",
    "validation_wolf_dir = os.path.join(validation_dir, 'WP')\n",
    "os.mkdir(validation_wolf_dir)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "convenient-least",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "407\n",
      "['LPZP.496.bmp', 'LPZP.300.bmp', 'LPZP.118.bmp', 'LPZP.149.bmp', 'LPZP.296.bmp', 'LPZP.75.bmp', 'LPZP.424.bmp', 'LPZP.464.bmp', 'LPZP.64.bmp', 'LPZP.62.bmp', 'LPZP.306.bmp', 'LPZP.206.bmp', 'LPZP.537.bmp', 'LPZP.17.bmp', 'LPZP.350.bmp', 'LPZP.46.bmp', 'LPZP.325.bmp', 'LPZP.63.bmp', 'LPZP.516.bmp', 'LPZP.249.bmp', 'LPZP.53.bmp', 'LPZP.455.bmp', 'LPZP.315.bmp', 'LPZP.70.bmp', 'LPZP.5.bmp', 'LPZP.401.bmp', 'LPZP.111.bmp', 'LPZP.14.bmp', 'LPZP.444.bmp', 'LPZP.58.bmp', 'LPZP.526.bmp', 'LPZP.407.bmp', 'LPZP.461.bmp', 'LPZP.204.bmp', 'LPZP.339.bmp', 'LPZP.129.bmp', 'LPZP.493.bmp', 'LPZP.135.bmp', 'LPZP.279.bmp', 'LPZP.354.bmp', 'LPZP.171.bmp', 'LPZP.11.bmp', 'LPZP.463.bmp', 'LPZP.241.bmp', 'LPZP.200.bmp', 'LPZP.0.bmp', 'LPZP.443.bmp', 'LPZP.280.bmp', 'LPZP.170.bmp', 'LPZP.392.bmp', 'LPZP.26.bmp', 'LPZP.38.bmp', 'LPZP.127.bmp', 'LPZP.34.bmp', 'LPZP.293.bmp', 'LPZP.484.bmp', 'LPZP.210.bmp', 'LPZP.353.bmp', 'LPZP.94.bmp', 'LPZP.52.bmp', 'LPZP.246.bmp', 'LPZP.272.bmp', 'LPZP.283.bmp', 'LPZP.449.bmp', 'LPZP.21.bmp', 'LPZP.261.bmp', 'LPZP.389.bmp', 'LPZP.82.bmp', 'LPZP.6.bmp', 'LPZP.379.bmp', 'LPZP.309.bmp', 'LPZP.372.bmp', 'LPZP.425.bmp', 'LPZP.235.bmp', 'LPZP.159.bmp', 'LPZP.362.bmp', 'LPZP.403.bmp', 'LPZP.67.bmp', 'LPZP.368.bmp', 'LPZP.105.bmp', 'LPZP.172.bmp', 'LPZP.356.bmp', 'LPZP.489.bmp', 'LPZP.472.bmp', 'LPZP.27.bmp', 'LPZP.74.bmp', 'LPZP.292.bmp', 'LPZP.447.bmp', 'LPZP.426.bmp', 'LPZP.258.bmp', 'LPZP.116.bmp', 'LPZP.65.bmp', 'LPZP.477.bmp', 'LPZP.29.bmp', 'LPZP.448.bmp', 'LPZP.406.bmp', 'LPZP.370.bmp', 'LPZP.20.bmp', 'LPZP.400.bmp', 'LPZP.380.bmp', 'LPZP.183.bmp', 'LPZP.193.bmp', 'LPZP.31.bmp', 'LPZP.487.bmp', 'LPZP.60.bmp', 'LPZP.365.bmp', 'LPZP.66.bmp', 'LPZP.474.bmp', 'LPZP.176.bmp', 'LPZP.138.bmp', 'LPZP.324.bmp', 'LPZP.504.bmp', 'LPZP.506.bmp', 'LPZP.189.bmp', 'LPZP.524.bmp', 'LPZP.128.bmp', 'LPZP.456.bmp', 'LPZP.192.bmp', 'LPZP.333.bmp', 'LPZP.412.bmp', 'LPZP.288.bmp', 'LPZP.393.bmp', 'LPZP.104.bmp', 'LPZP.480.bmp', 'LPZP.383.bmp', 'LPZP.152.bmp', 'LPZP.419.bmp', 'LPZP.251.bmp', 'LPZP.421.bmp', 'LPZP.523.bmp', 'LPZP.287.bmp', 'LPZP.181.bmp', 'LPZP.394.bmp', 'LPZP.386.bmp', 'LPZP.119.bmp', 'LPZP.103.bmp', 'LPZP.208.bmp', 'LPZP.469.bmp', 'LPZP.512.bmp', 'LPZP.173.bmp', 'LPZP.262.bmp', 'LPZP.19.bmp', 'LPZP.352.bmp', 'LPZP.194.bmp', 'LPZP.219.bmp', 'LPZP.373.bmp', 'LPZP.265.bmp', 'LPZP.161.bmp', 'LPZP.214.bmp', 'LPZP.408.bmp', 'LPZP.297.bmp', 'LPZP.231.bmp', 'LPZP.158.bmp', 'LPZP.462.bmp', 'LPZP.79.bmp', 'LPZP.201.bmp', 'LPZP.388.bmp', 'LPZP.182.bmp', 'LPZP.414.bmp', 'LPZP.96.bmp', 'LPZP.319.bmp', 'LPZP.92.bmp', 'LPZP.109.bmp', 'LPZP.242.bmp', 'LPZP.276.bmp', 'LPZP.162.bmp', 'LPZP.252.bmp', 'LPZP.374.bmp', 'LPZP.10.bmp', 'LPZP.39.bmp', 'LPZP.264.bmp', 'LPZP.110.bmp', 'LPZP.24.bmp', 'LPZP.378.bmp', 'LPZP.466.bmp', 'LPZP.117.bmp', 'LPZP.131.bmp', 'LPZP.143.bmp', 'LPZP.87.bmp', 'LPZP.108.bmp', 'LPZP.486.bmp', 'LPZP.44.bmp', 'LPZP.541.bmp', 'LPZP.188.bmp', 'LPZP.115.bmp', 'LPZP.314.bmp', 'LPZP.507.bmp', 'LPZP.180.bmp', 'LPZP.113.bmp', 'LPZP.263.bmp', 'LPZP.539.bmp', 'LPZP.514.bmp', 'LPZP.312.bmp', 'LPZP.491.bmp', 'LPZP.269.bmp', 'LPZP.422.bmp', 'LPZP.434.bmp', 'LPZP.346.bmp', 'LPZP.137.bmp', 'LPZP.185.bmp', 'LPZP.7.bmp', 'LPZP.471.bmp', 'LPZP.88.bmp', 'LPZP.411.bmp', 'LPZP.502.bmp', 'LPZP.30.bmp', 'LPZP.322.bmp', 'LPZP.366.bmp', 'LPZP.43.bmp', 'LPZP.435.bmp', 'LPZP.153.bmp', 'LPZP.453.bmp', 'LPZP.101.bmp', 'LPZP.323.bmp', 'LPZP.511.bmp', 'LPZP.9.bmp', 'LPZP.220.bmp', 'LPZP.470.bmp', 'LPZP.429.bmp', 'LPZP.358.bmp', 'LPZP.343.bmp', 'LPZP.331.bmp', 'LPZP.213.bmp', 'LPZP.197.bmp', 'LPZP.347.bmp', 'LPZP.260.bmp', 'LPZP.271.bmp', 'LPZP.133.bmp', 'LPZP.285.bmp', 'LPZP.147.bmp', 'LPZP.227.bmp', 'LPZP.291.bmp', 'LPZP.257.bmp', 'LPZP.51.bmp', 'LPZP.349.bmp', 'LPZP.4.bmp', 'LPZP.495.bmp', 'LPZP.340.bmp', 'LPZP.326.bmp', 'LPZP.360.bmp', 'LPZP.112.bmp', 'LPZP.361.bmp', 'LPZP.528.bmp', 'LPZP.317.bmp', 'LPZP.327.bmp', 'LPZP.243.bmp', 'LPZP.381.bmp', 'LPZP.190.bmp', 'LPZP.145.bmp', 'LPZP.56.bmp', 'LPZP.13.bmp', 'LPZP.239.bmp', 'LPZP.433.bmp', 'LPZP.202.bmp', 'LPZP.525.bmp', 'LPZP.48.bmp', 'LPZP.351.bmp', 'LPZP.270.bmp', 'LPZP.409.bmp', 'LPZP.95.bmp', 'LPZP.289.bmp', 'LPZP.536.bmp', 'LPZP.203.bmp', 'LPZP.37.bmp', 'LPZP.534.bmp', 'LPZP.428.bmp', 'LPZP.8.bmp', 'LPZP.156.bmp', 'LPZP.377.bmp', 'LPZP.382.bmp', 'LPZP.86.bmp', 'LPZP.282.bmp', 'LPZP.500.bmp', 'LPZP.42.bmp', 'LPZP.410.bmp', 'LPZP.330.bmp', 'LPZP.423.bmp', 'LPZP.404.bmp', 'LPZP.141.bmp', 'LPZP.295.bmp', 'LPZP.174.bmp', 'LPZP.458.bmp', 'LPZP.415.bmp', 'LPZP.417.bmp', 'LPZP.385.bmp', 'LPZP.402.bmp', 'LPZP.259.bmp', 'LPZP.150.bmp', 'LPZP.238.bmp', 'LPZP.144.bmp', 'LPZP.320.bmp', 'LPZP.303.bmp', 'LPZP.440.bmp', 'LPZP.328.bmp', 'LPZP.130.bmp', 'LPZP.391.bmp', 'LPZP.28.bmp', 'LPZP.337.bmp', 'LPZP.313.bmp', 'LPZP.533.bmp', 'LPZP.102.bmp', 'LPZP.195.bmp', 'LPZP.209.bmp', 'LPZP.217.bmp', 'LPZP.107.bmp', 'LPZP.3.bmp', 'LPZP.342.bmp', 'LPZP.186.bmp', 'LPZP.531.bmp', 'LPZP.441.bmp', 'LPZP.318.bmp', 'LPZP.535.bmp', 'LPZP.416.bmp', 'LPZP.387.bmp', 'LPZP.355.bmp', 'LPZP.237.bmp', 'LPZP.157.bmp', 'LPZP.498.bmp', 'LPZP.106.bmp', 'LPZP.218.bmp', 'LPZP.505.bmp', 'LPZP.302.bmp', 'LPZP.475.bmp', 'LPZP.93.bmp', 'LPZP.375.bmp', 'LPZP.98.bmp', 'LPZP.396.bmp', 'LPZP.304.bmp', 'LPZP.184.bmp', 'LPZP.72.bmp', 'LPZP.244.bmp', 'LPZP.83.bmp', 'LPZP.146.bmp', 'LPZP.54.bmp', 'LPZP.540.bmp', 'LPZP.305.bmp', 'LPZP.23.bmp', 'LPZP.527.bmp', 'LPZP.148.bmp', 'LPZP.126.bmp', 'LPZP.427.bmp', 'LPZP.151.bmp', 'LPZP.59.bmp', 'LPZP.12.bmp', 'LPZP.483.bmp', 'LPZP.321.bmp', 'LPZP.294.bmp', 'LPZP.301.bmp', 'LPZP.329.bmp', 'LPZP.100.bmp', 'LPZP.478.bmp', 'LPZP.446.bmp', 'LPZP.165.bmp', 'LPZP.121.bmp', 'LPZP.78.bmp', 'LPZP.445.bmp', 'LPZP.405.bmp', 'LPZP.436.bmp', 'LPZP.168.bmp', 'LPZP.216.bmp', 'LPZP.367.bmp', 'LPZP.357.bmp', 'LPZP.132.bmp', 'LPZP.175.bmp', 'LPZP.451.bmp', 'LPZP.485.bmp', 'LPZP.492.bmp', 'LPZP.234.bmp', 'LPZP.71.bmp', 'LPZP.248.bmp', 'LPZP.232.bmp', 'LPZP.311.bmp', 'LPZP.55.bmp', 'LPZP.530.bmp', 'LPZP.47.bmp', 'LPZP.179.bmp', 'LPZP.25.bmp', 'LPZP.490.bmp', 'LPZP.532.bmp', 'LPZP.224.bmp', 'LPZP.1.bmp', 'LPZP.479.bmp', 'LPZP.452.bmp', 'LPZP.50.bmp', 'LPZP.225.bmp', 'LPZP.286.bmp', 'LPZP.438.bmp', 'LPZP.359.bmp', 'LPZP.399.bmp', 'LPZP.198.bmp', 'LPZP.275.bmp', 'LPZP.454.bmp', 'LPZP.488.bmp', 'LPZP.277.bmp', 'LPZP.215.bmp', 'LPZP.69.bmp', 'LPZP.205.bmp', 'LPZP.236.bmp', 'LPZP.345.bmp', 'LPZP.250.bmp', 'LPZP.457.bmp', 'LPZP.32.bmp', 'LPZP.529.bmp', 'LPZP.308.bmp', 'LPZP.247.bmp', 'LPZP.266.bmp', 'LPZP.139.bmp']\n",
      "136\n",
      "['LPZP.520.bmp', 'LPZP.376.bmp', 'LPZP.123.bmp', 'LPZP.344.bmp', 'LPZP.253.bmp', 'LPZP.199.bmp', 'LPZP.81.bmp', 'LPZP.509.bmp', 'LPZP.207.bmp', 'LPZP.229.bmp', 'LPZP.134.bmp', 'LPZP.40.bmp', 'LPZP.124.bmp', 'LPZP.163.bmp', 'LPZP.169.bmp', 'LPZP.510.bmp', 'LPZP.364.bmp', 'LPZP.278.bmp', 'LPZP.508.bmp', 'LPZP.482.bmp', 'LPZP.222.bmp', 'LPZP.167.bmp', 'LPZP.177.bmp', 'LPZP.460.bmp', 'LPZP.513.bmp', 'LPZP.90.bmp', 'LPZP.398.bmp', 'LPZP.89.bmp', 'LPZP.420.bmp', 'LPZP.332.bmp', 'LPZP.338.bmp', 'LPZP.84.bmp', 'LPZP.476.bmp', 'LPZP.233.bmp', 'LPZP.515.bmp', 'LPZP.61.bmp', 'LPZP.442.bmp', 'LPZP.91.bmp', 'LPZP.267.bmp', 'LPZP.316.bmp', 'LPZP.73.bmp', 'LPZP.140.bmp', 'LPZP.348.bmp', 'LPZP.125.bmp', 'LPZP.228.bmp', 'LPZP.212.bmp', 'LPZP.221.bmp', 'LPZP.518.bmp', 'LPZP.97.bmp', 'LPZP.413.bmp', 'LPZP.85.bmp', 'LPZP.226.bmp', 'LPZP.49.bmp', 'LPZP.499.bmp', 'LPZP.397.bmp', 'LPZP.57.bmp', 'LPZP.468.bmp', 'LPZP.307.bmp', 'LPZP.191.bmp', 'LPZP.521.bmp', 'LPZP.196.bmp', 'LPZP.76.bmp', 'LPZP.41.bmp', 'LPZP.437.bmp', 'LPZP.273.bmp', 'LPZP.36.bmp', 'LPZP.336.bmp', 'LPZP.517.bmp', 'LPZP.418.bmp', 'LPZP.154.bmp', 'LPZP.254.bmp', 'LPZP.16.bmp', 'LPZP.18.bmp', 'LPZP.497.bmp', 'LPZP.538.bmp', 'LPZP.114.bmp', 'LPZP.522.bmp', 'LPZP.80.bmp', 'LPZP.256.bmp', 'LPZP.432.bmp', 'LPZP.166.bmp', 'LPZP.299.bmp', 'LPZP.334.bmp', 'LPZP.542.bmp', 'LPZP.240.bmp', 'LPZP.223.bmp', 'LPZP.230.bmp', 'LPZP.281.bmp', 'LPZP.341.bmp', 'LPZP.160.bmp', 'LPZP.122.bmp', 'LPZP.459.bmp', 'LPZP.395.bmp', 'LPZP.187.bmp', 'LPZP.274.bmp', 'LPZP.155.bmp', 'LPZP.465.bmp', 'LPZP.481.bmp', 'LPZP.99.bmp', 'LPZP.68.bmp', 'LPZP.120.bmp', 'LPZP.2.bmp', 'LPZP.298.bmp', 'LPZP.22.bmp', 'LPZP.384.bmp', 'LPZP.450.bmp', 'LPZP.245.bmp', 'LPZP.519.bmp', 'LPZP.136.bmp', 'LPZP.371.bmp', 'LPZP.310.bmp', 'LPZP.178.bmp', 'LPZP.467.bmp', 'LPZP.268.bmp', 'LPZP.290.bmp', 'LPZP.431.bmp', 'LPZP.390.bmp', 'LPZP.363.bmp', 'LPZP.142.bmp', 'LPZP.430.bmp', 'LPZP.45.bmp', 'LPZP.369.bmp', 'LPZP.255.bmp', 'LPZP.77.bmp', 'LPZP.335.bmp', 'LPZP.501.bmp', 'LPZP.35.bmp', 'LPZP.164.bmp', 'LPZP.284.bmp', 'LPZP.503.bmp', 'LPZP.473.bmp', 'LPZP.211.bmp', 'LPZP.15.bmp', 'LPZP.494.bmp', 'LPZP.439.bmp', 'LPZP.33.bmp']\n",
      "272\n",
      "['HESP.303.bmp', 'HESP.261.bmp', 'HESP.52.bmp', 'HESP.232.bmp', 'HESP.96.bmp', 'HESP.165.bmp', 'HESP.214.bmp', 'HESP.45.bmp', 'HESP.131.bmp', 'HESP.26.bmp', 'HESP.94.bmp', 'HESP.70.bmp', 'HESP.269.bmp', 'HESP.224.bmp', 'HESP.293.bmp', 'HESP.244.bmp', 'HESP.13.bmp', 'HESP.348.bmp', 'HESP.31.bmp', 'HESP.130.bmp', 'HESP.194.bmp', 'HESP.19.bmp', 'HESP.15.bmp', 'HESP.325.bmp', 'HESP.359.bmp', 'HESP.4.bmp', 'HESP.312.bmp', 'HESP.349.bmp', 'HESP.301.bmp', 'HESP.199.bmp', 'HESP.157.bmp', 'HESP.5.bmp', 'HESP.67.bmp', 'HESP.249.bmp', 'HESP.216.bmp', 'HESP.253.bmp', 'HESP.129.bmp', 'HESP.357.bmp', 'HESP.161.bmp', 'HESP.98.bmp', 'HESP.255.bmp', 'HESP.55.bmp', 'HESP.218.bmp', 'HESP.83.bmp', 'HESP.338.bmp', 'HESP.213.bmp', 'HESP.113.bmp', 'HESP.115.bmp', 'HESP.217.bmp', 'HESP.283.bmp', 'HESP.3.bmp', 'HESP.153.bmp', 'HESP.183.bmp', 'HESP.48.bmp', 'HESP.203.bmp', 'HESP.139.bmp', 'HESP.171.bmp', 'HESP.62.bmp', 'HESP.86.bmp', 'HESP.65.bmp', 'HESP.310.bmp', 'HESP.260.bmp', 'HESP.341.bmp', 'HESP.79.bmp', 'HESP.190.bmp', 'HESP.193.bmp', 'HESP.121.bmp', 'HESP.238.bmp', 'HESP.321.bmp', 'HESP.28.bmp', 'HESP.174.bmp', 'HESP.210.bmp', 'HESP.286.bmp', 'HESP.276.bmp', 'HESP.30.bmp', 'HESP.208.bmp', 'HESP.146.bmp', 'HESP.47.bmp', 'HESP.277.bmp', 'HESP.180.bmp', 'HESP.337.bmp', 'HESP.344.bmp', 'HESP.162.bmp', 'HESP.100.bmp', 'HESP.263.bmp', 'HESP.186.bmp', 'HESP.362.bmp', 'HESP.182.bmp', 'HESP.72.bmp', 'HESP.317.bmp', 'HESP.77.bmp', 'HESP.21.bmp', 'HESP.110.bmp', 'HESP.119.bmp', 'HESP.311.bmp', 'HESP.356.bmp', 'HESP.242.bmp', 'HESP.204.bmp', 'HESP.10.bmp', 'HESP.101.bmp', 'HESP.234.bmp', 'HESP.103.bmp', 'HESP.289.bmp', 'HESP.246.bmp', 'HESP.202.bmp', 'HESP.159.bmp', 'HESP.44.bmp', 'HESP.43.bmp', 'HESP.81.bmp', 'HESP.56.bmp', 'HESP.132.bmp', 'HESP.309.bmp', 'HESP.220.bmp', 'HESP.170.bmp', 'HESP.64.bmp', 'HESP.37.bmp', 'HESP.88.bmp', 'HESP.59.bmp', 'HESP.176.bmp', 'HESP.95.bmp', 'HESP.305.bmp', 'HESP.148.bmp', 'HESP.336.bmp', 'HESP.54.bmp', 'HESP.58.bmp', 'HESP.239.bmp', 'HESP.32.bmp', 'HESP.205.bmp', 'HESP.14.bmp', 'HESP.168.bmp', 'HESP.135.bmp', 'HESP.350.bmp', 'HESP.51.bmp', 'HESP.285.bmp', 'HESP.104.bmp', 'HESP.144.bmp', 'HESP.141.bmp', 'HESP.1.bmp', 'HESP.173.bmp', 'HESP.93.bmp', 'HESP.320.bmp', 'HESP.227.bmp', 'HESP.353.bmp', 'HESP.197.bmp', 'HESP.291.bmp', 'HESP.316.bmp', 'HESP.243.bmp', 'HESP.78.bmp', 'HESP.24.bmp', 'HESP.53.bmp', 'HESP.109.bmp', 'HESP.156.bmp', 'HESP.151.bmp', 'HESP.20.bmp', 'HESP.46.bmp', 'HESP.209.bmp', 'HESP.288.bmp', 'HESP.231.bmp', 'HESP.189.bmp', 'HESP.92.bmp', 'HESP.297.bmp', 'HESP.339.bmp', 'HESP.358.bmp', 'HESP.278.bmp', 'HESP.206.bmp', 'HESP.279.bmp', 'HESP.152.bmp', 'HESP.11.bmp', 'HESP.262.bmp', 'HESP.74.bmp', 'HESP.63.bmp', 'HESP.200.bmp', 'HESP.75.bmp', 'HESP.29.bmp', 'HESP.6.bmp', 'HESP.302.bmp', 'HESP.326.bmp', 'HESP.147.bmp', 'HESP.150.bmp', 'HESP.164.bmp', 'HESP.50.bmp', 'HESP.175.bmp', 'HESP.8.bmp', 'HESP.158.bmp', 'HESP.351.bmp', 'HESP.60.bmp', 'HESP.39.bmp', 'HESP.268.bmp', 'HESP.241.bmp', 'HESP.307.bmp', 'HESP.271.bmp', 'HESP.108.bmp', 'HESP.201.bmp', 'HESP.284.bmp', 'HESP.66.bmp', 'HESP.331.bmp', 'HESP.87.bmp', 'HESP.264.bmp', 'HESP.128.bmp', 'HESP.198.bmp', 'HESP.111.bmp', 'HESP.117.bmp', 'HESP.35.bmp', 'HESP.259.bmp', 'HESP.116.bmp', 'HESP.318.bmp', 'HESP.27.bmp', 'HESP.346.bmp', 'HESP.23.bmp', 'HESP.287.bmp', 'HESP.12.bmp', 'HESP.237.bmp', 'HESP.327.bmp', 'HESP.360.bmp', 'HESP.0.bmp', 'HESP.9.bmp', 'HESP.282.bmp', 'HESP.106.bmp', 'HESP.25.bmp', 'HESP.112.bmp', 'HESP.143.bmp', 'HESP.355.bmp', 'HESP.179.bmp', 'HESP.354.bmp', 'HESP.252.bmp', 'HESP.137.bmp', 'HESP.270.bmp', 'HESP.340.bmp', 'HESP.138.bmp', 'HESP.107.bmp', 'HESP.34.bmp', 'HESP.102.bmp', 'HESP.306.bmp', 'HESP.118.bmp', 'HESP.248.bmp', 'HESP.280.bmp', 'HESP.42.bmp', 'HESP.300.bmp', 'HESP.345.bmp', 'HESP.272.bmp', 'HESP.123.bmp', 'HESP.133.bmp', 'HESP.69.bmp', 'HESP.296.bmp', 'HESP.257.bmp', 'HESP.188.bmp', 'HESP.275.bmp', 'HESP.313.bmp', 'HESP.172.bmp', 'HESP.126.bmp', 'HESP.265.bmp', 'HESP.235.bmp', 'HESP.319.bmp', 'HESP.258.bmp', 'HESP.149.bmp', 'HESP.207.bmp', 'HESP.229.bmp', 'HESP.335.bmp', 'HESP.40.bmp', 'HESP.124.bmp', 'HESP.163.bmp', 'HESP.169.bmp', 'HESP.324.bmp', 'HESP.322.bmp', 'HESP.304.bmp', 'HESP.222.bmp', 'HESP.347.bmp', 'HESP.177.bmp', 'HESP.245.bmp', 'HESP.90.bmp', 'HESP.333.bmp', 'HESP.84.bmp']\n",
      "91\n",
      "['HESP.323.bmp', 'HESP.329.bmp', 'HESP.136.bmp', 'HESP.61.bmp', 'HESP.91.bmp', 'HESP.267.bmp', 'HESP.73.bmp', 'HESP.140.bmp', 'HESP.125.bmp', 'HESP.228.bmp', 'HESP.212.bmp', 'HESP.221.bmp', 'HESP.178.bmp', 'HESP.97.bmp', 'HESP.85.bmp', 'HESP.226.bmp', 'HESP.49.bmp', 'HESP.57.bmp', 'HESP.294.bmp', 'HESP.191.bmp', 'HESP.290.bmp', 'HESP.196.bmp', 'HESP.76.bmp', 'HESP.41.bmp', 'HESP.273.bmp', 'HESP.36.bmp', 'HESP.154.bmp', 'HESP.254.bmp', 'HESP.361.bmp', 'HESP.18.bmp', 'HESP.315.bmp', 'HESP.211.bmp', 'HESP.114.bmp', 'HESP.80.bmp', 'HESP.256.bmp', 'HESP.166.bmp', 'HESP.299.bmp', 'HESP.33.bmp', 'HESP.240.bmp', 'HESP.223.bmp', 'HESP.230.bmp', 'HESP.281.bmp', 'HESP.160.bmp', 'HESP.328.bmp', 'HESP.187.bmp', 'HESP.274.bmp', 'HESP.332.bmp', 'HESP.99.bmp', 'HESP.330.bmp', 'HESP.120.bmp', 'HESP.2.bmp', 'HESP.298.bmp', 'HESP.343.bmp', 'HESP.192.bmp', 'HESP.314.bmp', 'HESP.225.bmp', 'HESP.122.bmp', 'HESP.352.bmp', 'HESP.68.bmp', 'HESP.185.bmp', 'HESP.155.bmp', 'HESP.89.bmp', 'HESP.233.bmp', 'HESP.134.bmp', 'HESP.145.bmp', 'HESP.342.bmp', 'HESP.195.bmp', 'HESP.181.bmp', 'HESP.308.bmp', 'HESP.71.bmp', 'HESP.215.bmp', 'HESP.22.bmp', 'HESP.184.bmp', 'HESP.127.bmp', 'HESP.38.bmp', 'HESP.167.bmp', 'HESP.250.bmp', 'HESP.266.bmp', 'HESP.17.bmp', 'HESP.82.bmp', 'HESP.334.bmp', 'HESP.142.bmp', 'HESP.251.bmp', 'HESP.236.bmp', 'HESP.105.bmp', 'HESP.7.bmp', 'HESP.295.bmp', 'HESP.247.bmp', 'HESP.219.bmp', 'HESP.16.bmp', 'HESP.292.bmp']\n",
      "150\n",
      "['WP.12.bmp', 'WP.78.bmp', 'WP.104.bmp', 'WP.36.bmp', 'WP.160.bmp', 'WP.162.bmp', 'WP.48.bmp', 'WP.130.bmp', 'WP.68.bmp', 'WP.135.bmp', 'WP.89.bmp', 'WP.193.bmp', 'WP.64.bmp', 'WP.45.bmp', 'WP.14.bmp', 'WP.23.bmp', 'WP.7.bmp', 'WP.13.bmp', 'WP.39.bmp', 'WP.50.bmp', 'WP.54.bmp', 'WP.43.bmp', 'WP.25.bmp', 'WP.196.bmp', 'WP.114.bmp', 'WP.81.bmp', 'WP.46.bmp', 'WP.85.bmp', 'WP.158.bmp', 'WP.183.bmp', 'WP.82.bmp', 'WP.197.bmp', 'WP.47.bmp', 'WP.37.bmp', 'WP.88.bmp', 'WP.161.bmp', 'WP.145.bmp', 'WP.190.bmp', 'WP.126.bmp', 'WP.32.bmp', 'WP.27.bmp', 'WP.73.bmp', 'WP.173.bmp', 'WP.165.bmp', 'WP.29.bmp', 'WP.106.bmp', 'WP.174.bmp', 'WP.138.bmp', 'WP.176.bmp', 'WP.100.bmp', 'WP.194.bmp', 'WP.4.bmp', 'WP.76.bmp', 'WP.189.bmp', 'WP.152.bmp', 'WP.2.bmp', 'WP.75.bmp', 'WP.26.bmp', 'WP.6.bmp', 'WP.94.bmp', 'WP.148.bmp', 'WP.86.bmp', 'WP.65.bmp', 'WP.70.bmp', 'WP.150.bmp', 'WP.175.bmp', 'WP.119.bmp', 'WP.17.bmp', 'WP.124.bmp', 'WP.59.bmp', 'WP.62.bmp', 'WP.159.bmp', 'WP.153.bmp', 'WP.113.bmp', 'WP.101.bmp', 'WP.163.bmp', 'WP.108.bmp', 'WP.171.bmp', 'WP.30.bmp', 'WP.182.bmp', 'WP.155.bmp', 'WP.186.bmp', 'WP.74.bmp', 'WP.51.bmp', 'WP.192.bmp', 'WP.33.bmp', 'WP.10.bmp', 'WP.117.bmp', 'WP.142.bmp', 'WP.42.bmp', 'WP.5.bmp', 'WP.91.bmp', 'WP.69.bmp', 'WP.0.bmp', 'WP.143.bmp', 'WP.199.bmp', 'WP.188.bmp', 'WP.122.bmp', 'WP.131.bmp', 'WP.139.bmp', 'WP.102.bmp', 'WP.99.bmp', 'WP.195.bmp', 'WP.144.bmp', 'WP.84.bmp', 'WP.185.bmp', 'WP.129.bmp', 'WP.58.bmp', 'WP.156.bmp', 'WP.15.bmp', 'WP.110.bmp', 'WP.22.bmp', 'WP.66.bmp', 'WP.79.bmp', 'WP.134.bmp', 'WP.178.bmp', 'WP.87.bmp', 'WP.31.bmp', 'WP.141.bmp', 'WP.53.bmp', 'WP.55.bmp', 'WP.169.bmp', 'WP.121.bmp', 'WP.136.bmp', 'WP.103.bmp', 'WP.21.bmp', 'WP.56.bmp', 'WP.24.bmp', 'WP.28.bmp', 'WP.132.bmp', 'WP.95.bmp', 'WP.98.bmp', 'WP.38.bmp', 'WP.20.bmp', 'WP.18.bmp', 'WP.177.bmp', 'WP.127.bmp', 'WP.187.bmp', 'WP.9.bmp', 'WP.151.bmp', 'WP.105.bmp', 'WP.57.bmp', 'WP.40.bmp', 'WP.128.bmp', 'WP.184.bmp', 'WP.16.bmp', 'WP.120.bmp', 'WP.111.bmp', 'WP.115.bmp', 'WP.140.bmp']\n",
      "50\n",
      "['WP.80.bmp', 'WP.164.bmp', 'WP.93.bmp', 'WP.137.bmp', 'WP.168.bmp', 'WP.49.bmp', 'WP.166.bmp', 'WP.60.bmp', 'WP.1.bmp', 'WP.149.bmp', 'WP.180.bmp', 'WP.96.bmp', 'WP.157.bmp', 'WP.112.bmp', 'WP.61.bmp', 'WP.170.bmp', 'WP.34.bmp', 'WP.181.bmp', 'WP.77.bmp', 'WP.44.bmp', 'WP.116.bmp', 'WP.67.bmp', 'WP.172.bmp', 'WP.72.bmp', 'WP.179.bmp', 'WP.97.bmp', 'WP.90.bmp', 'WP.154.bmp', 'WP.35.bmp', 'WP.107.bmp', 'WP.11.bmp', 'WP.92.bmp', 'WP.63.bmp', 'WP.19.bmp', 'WP.83.bmp', 'WP.191.bmp', 'WP.133.bmp', 'WP.198.bmp', 'WP.41.bmp', 'WP.167.bmp', 'WP.71.bmp', 'WP.125.bmp', 'WP.118.bmp', 'WP.52.bmp', 'WP.3.bmp', 'WP.147.bmp', 'WP.123.bmp', 'WP.109.bmp', 'WP.8.bmp', 'WP.146.bmp']\n"
     ]
    }
   ],
   "source": [
    "#USE THIS ONE\n",
    "\n",
    "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
    "# randomize order of image locations\n",
    "# this will help model in not being data sequence dependent\n",
    "\n",
    "# Copy first CM images to train_lion_dir\n",
    "import random\n",
    "    \n",
    "    \n",
    "\n",
    "# Copy first TM images to train_leop_dir # \n",
    "fnames = ['LPZP.{}.bmp'.format(i) for i in range(543)]\n",
    "random.seed(10)\n",
    "random.shuffle(fnames)\n",
    "fnamest = fnames[0:407]\n",
    "print(len(fnamest))\n",
    "print(fnamest)\n",
    "\n",
    "for fname in fnamest:\n",
    "    src = os.path.join(original_dir, fname)\n",
    "    dst = os.path.join(train_leop_dir, fname)\n",
    "    shutil.copyfile(src, dst)\n",
    "        \n",
    "# Copy next 10 TM images to validation_leop_dir\n",
    "fnamesv = fnames[407:543]\n",
    "print(len(fnamesv))\n",
    "print(fnamesv)\n",
    "for fname in fnamesv:\n",
    "    src = os.path.join(original_dir, fname)\n",
    "    dst = os.path.join(validation_leop_dir, fname)\n",
    "    shutil.copyfile(src, dst)\n",
    "         \n",
    "        \n",
    "    \n",
    "# Copy first TM images to train_hyena_dir # \n",
    "fnames = ['HESP.{}.bmp'.format(i) for i in range(363)]\n",
    "random.seed(10)\n",
    "random.shuffle(fnames)\n",
    "fnamest = fnames[0:272]\n",
    "print(len(fnamest))\n",
    "print(fnamest)\n",
    "\n",
    "for fname in fnamest:\n",
    "    src = os.path.join(original_dir, fname)\n",
    "    dst = os.path.join(train_hyena_dir, fname)\n",
    "    shutil.copyfile(src, dst)\n",
    "        \n",
    "# Copy next 10 TM images to validation_hip_dir\n",
    "fnamesv = fnames[272:363]\n",
    "print(len(fnamesv))\n",
    "print(fnamesv)\n",
    "for fname in fnamesv:\n",
    "    src = os.path.join(original_dir, fname)\n",
    "    dst = os.path.join(validation_hyena_dir, fname)\n",
    "    shutil.copyfile(src, dst)\n",
    "\n",
    "\n",
    "# Copy first TM images to train_wolf_dir # \n",
    "fnames = ['WP.{}.bmp'.format(i) for i in range(200)]\n",
    "random.seed(10)\n",
    "random.shuffle(fnames)\n",
    "fnamest = fnames[0:150]\n",
    "print(len(fnamest))\n",
    "print(fnamest)\n",
    "\n",
    "for fname in fnamest:\n",
    "    src = os.path.join(original_dir, fname)\n",
    "    dst = os.path.join(train_wolf_dir, fname)\n",
    "    shutil.copyfile(src, dst)\n",
    "        \n",
    "# Copy next 10 TM images to validation_red_dir\n",
    "fnamesv = fnames[150:200]\n",
    "print(len(fnamesv))\n",
    "print(fnamesv)\n",
    "for fname in fnamesv:\n",
    "    src = os.path.join(original_dir, fname)\n",
    "    dst = os.path.join(validation_wolf_dir, fname)\n",
    "    shutil.copyfile(src, dst)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "efe09e3f",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#training and testing sets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "02b116cf",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4e98e48e",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 456,
   "id": "0b730d9a",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 829 images belonging to 3 classes.\n",
      "Found 277 images belonging to 3 classes.\n"
     ]
    }
   ],
   "source": [
    "from tensorflow.keras.applications.resnet50 import preprocess_input #for RESNET 50\n",
    "#from tensorflow.keras.applications.imagenet_utils import decode_predictions, preprocess_input#for efficient Net\n",
    "\n",
    "#Let's train our network using data augmentation and dropout:\n",
    "train_datagen = ImageDataGenerator(\n",
    "    rotation_range=40,\n",
    "    width_shift_range=0.2,\n",
    "    height_shift_range=0.2,\n",
    "    shear_range=0.2,\n",
    "    zoom_range=0.2,\n",
    "    horizontal_flip=True,\n",
    "    preprocessing_function= \\\n",
    "    keras.applications.resnet50.preprocess_input)#OJO!!!! imagenet_utils for Efficient Net\n",
    "\n",
    "# Note that the validation data should not be augmented!\n",
    "test_datagen = ImageDataGenerator(preprocessing_function= \\\n",
    "    keras.applications.resnet50.preprocess_input)#OJO!!!\n",
    "\n",
    "train_generator = train_datagen.flow_from_directory(\n",
    "        # This is the target directory\n",
    "        train_dir,\n",
    "        # All images will be resized \n",
    "        target_size=(250, 200),\n",
    "        batch_size=64,\n",
    "        class_mode='categorical')#put \"categorical\" si son más de 2 categorías\n",
    "\n",
    "validation_generator = test_datagen.flow_from_directory(\n",
    "        validation_dir,\n",
    "        target_size=(250, 200),\n",
    "        batch_size=32,\n",
    "        class_mode='categorical',\n",
    "        shuffle=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "original-above",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 829 images belonging to 3 classes.\n",
      "Found 277 images belonging to 3 classes.\n",
      "(829, 250, 200, 3) train samples\n",
      "(277, 250, 200, 3) test samples\n"
     ]
    }
   ],
   "source": [
    "datagenTrain=train_datagen.flow_from_directory(\n",
    "        # This is the target directory\n",
    "        train_dir,\n",
    "        # All images will be resized to 40x160\n",
    "        target_size=(250,200),\n",
    "        batch_size=829,\n",
    "        # Since we use binary_crossentropy loss, we need binary labels\n",
    "        class_mode='categorical')\n",
    "datagenTest=test_datagen.flow_from_directory(\n",
    "        # This is the target directory\n",
    "        validation_dir,\n",
    "        # All images will be resized to 40x160\n",
    "        target_size=(250, 200),\n",
    "        batch_size=277,\n",
    "        # Since we use binary_crossentropy loss, we need binary labels\n",
    "        class_mode='categorical',\n",
    "        shuffle=False)\n",
    "x_train, y_train = next(datagenTrain)\n",
    "x_test, y_test = next(datagenTest)\n",
    "print(x_train.shape, 'train samples')\n",
    "print(x_test.shape, 'test samples')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "62521d75",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "af7b5cdc",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#MODULE 2: CHOOSE MODEL"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0d1d0fac",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# For adding new activation function\n",
    "from keras.layers import Activation\n",
    "from keras import backend as K\n",
    "from tensorflow.python.keras.utils.generic_utils import get_custom_objects\n",
    "#from keras.utils.generic_utils import get_custom_objects\n",
    "def swish(x):\n",
    "    return (K.sigmoid(x) * x)\n",
    "\n",
    "get_custom_objects().update({'swish': Activation(swish)})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "566a8bbd",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#activate Dropout and Early Stopping"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "ece170ec",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:absl:`lr` is deprecated in Keras optimizer, please use `learning_rate` or use the legacy optimizer, e.g.,tf.keras.optimizers.legacy.SGD.\n"
     ]
    }
   ],
   "source": [
    "# Vgg19 for transfer learning with Dropout\n",
    "import sys\n",
    "\n",
    "from matplotlib import pyplot\n",
    "from tensorflow.keras.applications.vgg19 import VGG19\n",
    "from keras.models import Model\n",
    "from keras.layers import Dense\n",
    "from keras.layers import Flatten\n",
    "from keras.layers import Dropout\n",
    "#from keras.optimizers import SGD\n",
    "from keras.optimizers import Adagrad\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "\n",
    "\n",
    "\n",
    "# define cnn model\n",
    "def define_model():\n",
    "\t# load model\n",
    "\tmodel = VGG19(include_top=False, input_shape=(250, 200, 3))\n",
    "\t# mark loaded layers as not trainable\n",
    "\tfor layer in model.layers:\n",
    "\t\tlayer.trainable = False\n",
    "\t# add new classifier layers\n",
    "\tflat1 = Flatten()(model.layers[-1].output)\n",
    "\tclass1 = Dense(128, activation='swish', kernel_initializer='he_uniform')(flat1)\n",
    "\tdrop=Dropout(0.3)(class1)\n",
    "\toutput = Dense(3, activation='softmax')(drop)\n",
    "\t# define new model\n",
    "\tmodel = Model(inputs=model.inputs, outputs=output)\n",
    "\t# compile model\n",
    "\topt = SGD(lr=0.001, momentum=0.9)\n",
    "\t#opt = Adagrad (lr=0.001)\n",
    "\tmodel.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])\n",
    "\treturn model\n",
    "\n",
    "# define model\n",
    "model = define_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "21114903",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 454,
   "id": "complicated-college",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:absl:`lr` is deprecated in Keras optimizer, please use `learning_rate` or use the legacy optimizer, e.g.,tf.keras.optimizers.legacy.Adagrad.\n"
     ]
    }
   ],
   "source": [
    "# for transfer learning RESNET50 with Dropout\n",
    "import sys\n",
    "from matplotlib import pyplot\n",
    "from tensorflow.keras.applications.resnet50 import ResNet50\n",
    "from keras.models import Model\n",
    "from keras.layers import Dense\n",
    "from keras.layers import Flatten\n",
    "from keras.layers import Dropout\n",
    "from keras.optimizers import SGD\n",
    "from keras.optimizers import Adagrad\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "\n",
    "# define cnn model\n",
    "def define_model():\n",
    "\t# load model\n",
    "\tmodel = ResNet50(include_top=False, input_shape=(250, 200, 3))\n",
    "\t# mark loaded layers as not trainable\n",
    "\tfor layer in model.layers:\n",
    "\t\tlayer.trainable = False\n",
    "\t# add new classifier layers\n",
    "\tflat1 = Flatten()(model.layers[-1].output)\n",
    "\tclass1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)\n",
    "\tdrop=Dropout(0.3)(class1)\n",
    "\toutput = Dense(3, activation='softmax')(drop)\n",
    "\t# define new model\n",
    "\tmodel = Model(inputs=model.inputs, outputs=output)\n",
    "\t# compile model\n",
    "\t#opt = SGD(lr=0.001, momentum=0.9)\n",
    "\topt = Adagrad(lr=0.001)\n",
    "\tmodel.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])\n",
    "\treturn model\n",
    "\n",
    "# define model\n",
    "model = define_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "50a09b9a",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "id": "be5f7ef8",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:absl:`lr` is deprecated in Keras optimizer, please use `learning_rate` or use the legacy optimizer, e.g.,tf.keras.optimizers.legacy.SGD.\n"
     ]
    }
   ],
   "source": [
    "# for transfer learning DENSENET with Dropout\n",
    "import sys\n",
    "from matplotlib import pyplot\n",
    "from tensorflow.keras.applications.densenet import DenseNet201\n",
    "from keras.models import Model\n",
    "from keras.layers import Dense\n",
    "from keras.layers import Flatten\n",
    "from keras.layers import Dropout\n",
    "from keras.optimizers import SGD\n",
    "from keras.optimizers import Adagrad\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "\n",
    "# define cnn model\n",
    "def define_model():\n",
    "\t# load model\n",
    "\tmodel = DenseNet201(include_top=False, input_shape=(250, 200, 3))\n",
    "\t# mark loaded layers as not trainable\n",
    "\tfor layer in model.layers:\n",
    "\t\tlayer.trainable = False\n",
    "\t# add new classifier layers\n",
    "\tflat1 = Flatten()(model.layers[-1].output)\n",
    "\tclass1 = Dense(128, activation='swish', kernel_initializer='he_uniform')(flat1)\n",
    "\tdrop=Dropout(0.3)(class1)\n",
    "\toutput = Dense(3, activation='softmax')(drop)\n",
    "\t# define new model\n",
    "\tmodel = Model(inputs=model.inputs, outputs=output)\n",
    "\t# compile \n",
    "\topt = SGD(lr=0.001, momentum=0.9)   \n",
    "\t#opt = Adagrad(lr=0.001)\n",
    "\tmodel.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])\n",
    "\treturn model\n",
    "\n",
    "# define model\n",
    "model = define_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "703e6c3c",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6fc143a8",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#RUN MODEL:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 455,
   "id": "f73ae474",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\oscar\\AppData\\Local\\Temp\\ipykernel_1280\\2756996010.py:2: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.\n",
      "  history = model.fit_generator(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/100\n",
      "13/13 [==============================] - 38s 3s/step - loss: 3.4221 - accuracy: 0.5481 - val_loss: 0.6592 - val_accuracy: 0.7000\n",
      "Epoch 2/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.6123 - accuracy: 0.7312 - val_loss: 0.5138 - val_accuracy: 0.7389\n",
      "Epoch 3/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.5512 - accuracy: 0.7692 - val_loss: 0.3866 - val_accuracy: 0.8056\n",
      "Epoch 4/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.4860 - accuracy: 0.7812 - val_loss: 0.3745 - val_accuracy: 0.8167\n",
      "Epoch 5/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.4257 - accuracy: 0.7981 - val_loss: 0.4556 - val_accuracy: 0.7500\n",
      "Epoch 6/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.3780 - accuracy: 0.8317 - val_loss: 0.4460 - val_accuracy: 0.8111\n",
      "Epoch 7/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.3606 - accuracy: 0.8329 - val_loss: 0.3224 - val_accuracy: 0.8056\n",
      "Epoch 8/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.3881 - accuracy: 0.8221 - val_loss: 0.3823 - val_accuracy: 0.8389\n",
      "Epoch 9/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.3143 - accuracy: 0.8571 - val_loss: 0.3745 - val_accuracy: 0.8056\n",
      "Epoch 10/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.3090 - accuracy: 0.8582 - val_loss: 0.3711 - val_accuracy: 0.7833\n",
      "Epoch 11/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.2881 - accuracy: 0.8630 - val_loss: 0.3806 - val_accuracy: 0.7833\n",
      "Epoch 12/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.3040 - accuracy: 0.8523 - val_loss: 0.3923 - val_accuracy: 0.8167\n",
      "Epoch 13/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.2627 - accuracy: 0.8644 - val_loss: 0.4067 - val_accuracy: 0.8222\n",
      "Epoch 14/100\n",
      "13/13 [==============================] - 36s 3s/step - loss: 0.3465 - accuracy: 0.8232 - val_loss: 0.4716 - val_accuracy: 0.7889\n",
      "Epoch 15/100\n",
      "13/13 [==============================] - 36s 3s/step - loss: 0.3100 - accuracy: 0.8475 - val_loss: 0.4426 - val_accuracy: 0.7889\n",
      "Epoch 16/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2668 - accuracy: 0.8846 - val_loss: 0.3650 - val_accuracy: 0.8444\n",
      "Epoch 17/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2900 - accuracy: 0.8741 - val_loss: 0.4062 - val_accuracy: 0.8444\n",
      "Epoch 18/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2503 - accuracy: 0.8894 - val_loss: 0.3307 - val_accuracy: 0.8278\n",
      "Epoch 19/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2481 - accuracy: 0.8894 - val_loss: 0.3394 - val_accuracy: 0.8556\n",
      "Epoch 20/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2490 - accuracy: 0.8717 - val_loss: 0.3125 - val_accuracy: 0.8333\n",
      "Epoch 21/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2477 - accuracy: 0.8814 - val_loss: 0.3234 - val_accuracy: 0.8333\n",
      "Epoch 22/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2209 - accuracy: 0.9007 - val_loss: 0.3110 - val_accuracy: 0.8667\n",
      "Epoch 23/100\n",
      "13/13 [==============================] - 36s 3s/step - loss: 0.2420 - accuracy: 0.8846 - val_loss: 0.3548 - val_accuracy: 0.8222\n",
      "Epoch 24/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2274 - accuracy: 0.8894 - val_loss: 0.3463 - val_accuracy: 0.8556\n",
      "Epoch 25/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2007 - accuracy: 0.9062 - val_loss: 0.3803 - val_accuracy: 0.8444\n",
      "Epoch 26/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.2367 - accuracy: 0.8838 - val_loss: 0.3956 - val_accuracy: 0.8222\n",
      "Epoch 27/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2319 - accuracy: 0.9007 - val_loss: 0.3583 - val_accuracy: 0.8611\n",
      "Epoch 28/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2238 - accuracy: 0.8966 - val_loss: 0.3199 - val_accuracy: 0.8778\n",
      "Epoch 29/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2061 - accuracy: 0.8966 - val_loss: 0.3478 - val_accuracy: 0.8556\n",
      "Epoch 30/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2314 - accuracy: 0.9014 - val_loss: 0.3542 - val_accuracy: 0.8222\n",
      "Epoch 31/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2166 - accuracy: 0.9128 - val_loss: 0.3506 - val_accuracy: 0.8167\n",
      "Epoch 32/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2228 - accuracy: 0.8935 - val_loss: 0.3191 - val_accuracy: 0.8556\n",
      "Epoch 33/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2083 - accuracy: 0.9135 - val_loss: 0.3568 - val_accuracy: 0.8444\n",
      "Epoch 34/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1983 - accuracy: 0.9135 - val_loss: 0.3140 - val_accuracy: 0.8611\n",
      "Epoch 35/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2030 - accuracy: 0.9014 - val_loss: 0.4370 - val_accuracy: 0.7833\n",
      "Epoch 36/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.2166 - accuracy: 0.8918 - val_loss: 0.3411 - val_accuracy: 0.8111\n",
      "Epoch 37/100\n",
      "13/13 [==============================] - 36s 3s/step - loss: 0.1892 - accuracy: 0.9159 - val_loss: 0.3857 - val_accuracy: 0.8500\n",
      "Epoch 38/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1817 - accuracy: 0.9231 - val_loss: 0.3972 - val_accuracy: 0.8667\n",
      "Epoch 39/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1892 - accuracy: 0.9080 - val_loss: 0.3100 - val_accuracy: 0.8556\n",
      "Epoch 40/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.2241 - accuracy: 0.8774 - val_loss: 0.3734 - val_accuracy: 0.8611\n",
      "Epoch 41/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.1964 - accuracy: 0.9153 - val_loss: 0.3210 - val_accuracy: 0.8556\n",
      "Epoch 42/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1903 - accuracy: 0.9225 - val_loss: 0.3226 - val_accuracy: 0.8833\n",
      "Epoch 43/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2140 - accuracy: 0.8846 - val_loss: 0.3320 - val_accuracy: 0.8444\n",
      "Epoch 44/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2179 - accuracy: 0.8959 - val_loss: 0.3407 - val_accuracy: 0.8278\n",
      "Epoch 45/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1969 - accuracy: 0.9274 - val_loss: 0.3258 - val_accuracy: 0.8667\n",
      "Epoch 46/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.1953 - accuracy: 0.9014 - val_loss: 0.3266 - val_accuracy: 0.8833\n",
      "Epoch 47/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.1848 - accuracy: 0.9231 - val_loss: 0.3418 - val_accuracy: 0.8889\n",
      "Epoch 48/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2081 - accuracy: 0.8983 - val_loss: 0.2936 - val_accuracy: 0.8667\n",
      "Epoch 49/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.2158 - accuracy: 0.9007 - val_loss: 0.2813 - val_accuracy: 0.8944\n",
      "Epoch 50/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1797 - accuracy: 0.9201 - val_loss: 0.3286 - val_accuracy: 0.8778\n",
      "Epoch 51/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.1748 - accuracy: 0.9225 - val_loss: 0.3182 - val_accuracy: 0.8889\n",
      "Epoch 52/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.1818 - accuracy: 0.9274 - val_loss: 0.2987 - val_accuracy: 0.8778\n",
      "Epoch 53/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1819 - accuracy: 0.9375 - val_loss: 0.3292 - val_accuracy: 0.8722\n",
      "Epoch 54/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1629 - accuracy: 0.9201 - val_loss: 0.2931 - val_accuracy: 0.8944\n",
      "Epoch 55/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.1758 - accuracy: 0.9201 - val_loss: 0.2815 - val_accuracy: 0.8556\n",
      "Epoch 56/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1492 - accuracy: 0.9279 - val_loss: 0.2966 - val_accuracy: 0.8778\n",
      "Epoch 57/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1980 - accuracy: 0.9177 - val_loss: 0.2769 - val_accuracy: 0.8611\n",
      "Epoch 58/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.1800 - accuracy: 0.9207 - val_loss: 0.2943 - val_accuracy: 0.8556\n",
      "Epoch 59/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1771 - accuracy: 0.9298 - val_loss: 0.2969 - val_accuracy: 0.8611\n",
      "Epoch 60/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.1838 - accuracy: 0.9031 - val_loss: 0.3318 - val_accuracy: 0.8611\n",
      "Epoch 61/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1761 - accuracy: 0.9056 - val_loss: 0.2936 - val_accuracy: 0.8889\n",
      "Epoch 62/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1433 - accuracy: 0.9375 - val_loss: 0.3043 - val_accuracy: 0.8556\n",
      "Epoch 63/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1674 - accuracy: 0.9327 - val_loss: 0.2916 - val_accuracy: 0.8833\n",
      "Epoch 64/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1661 - accuracy: 0.9225 - val_loss: 0.2988 - val_accuracy: 0.8667\n",
      "Epoch 65/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1483 - accuracy: 0.9375 - val_loss: 0.2894 - val_accuracy: 0.8778\n",
      "Epoch 66/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1675 - accuracy: 0.9303 - val_loss: 0.2863 - val_accuracy: 0.8778\n",
      "Epoch 67/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1846 - accuracy: 0.9225 - val_loss: 0.3091 - val_accuracy: 0.8611\n",
      "Epoch 68/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1579 - accuracy: 0.9443 - val_loss: 0.3158 - val_accuracy: 0.8778\n",
      "Epoch 69/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1692 - accuracy: 0.9249 - val_loss: 0.3037 - val_accuracy: 0.8889\n",
      "Epoch 70/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1558 - accuracy: 0.9303 - val_loss: 0.3026 - val_accuracy: 0.8722\n",
      "Epoch 71/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1667 - accuracy: 0.9231 - val_loss: 0.3002 - val_accuracy: 0.8889\n",
      "Epoch 72/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1597 - accuracy: 0.9395 - val_loss: 0.2949 - val_accuracy: 0.8833\n",
      "Epoch 73/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1784 - accuracy: 0.9231 - val_loss: 0.2921 - val_accuracy: 0.8833\n",
      "Epoch 74/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1153 - accuracy: 0.9370 - val_loss: 0.3170 - val_accuracy: 0.8722\n",
      "Epoch 75/100\n",
      "13/13 [==============================] - 35s 3s/step - loss: 0.1401 - accuracy: 0.9419 - val_loss: 0.3041 - val_accuracy: 0.8500\n",
      "Epoch 76/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1732 - accuracy: 0.9159 - val_loss: 0.2734 - val_accuracy: 0.8778\n",
      "Epoch 77/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1463 - accuracy: 0.9298 - val_loss: 0.3025 - val_accuracy: 0.8944\n",
      "Epoch 78/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1417 - accuracy: 0.9516 - val_loss: 0.3126 - val_accuracy: 0.8722\n",
      "Epoch 79/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1411 - accuracy: 0.9443 - val_loss: 0.2934 - val_accuracy: 0.8944\n",
      "Epoch 80/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1609 - accuracy: 0.9274 - val_loss: 0.2895 - val_accuracy: 0.8667\n",
      "Epoch 81/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1574 - accuracy: 0.9322 - val_loss: 0.3110 - val_accuracy: 0.8778\n",
      "Epoch 82/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1549 - accuracy: 0.9255 - val_loss: 0.2958 - val_accuracy: 0.9056\n",
      "Epoch 83/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1267 - accuracy: 0.9540 - val_loss: 0.2823 - val_accuracy: 0.8833\n",
      "Epoch 84/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1339 - accuracy: 0.9399 - val_loss: 0.3441 - val_accuracy: 0.8611\n",
      "Epoch 85/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1186 - accuracy: 0.9588 - val_loss: 0.3007 - val_accuracy: 0.8667\n",
      "Epoch 86/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1249 - accuracy: 0.9467 - val_loss: 0.3153 - val_accuracy: 0.8667\n",
      "Epoch 87/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1288 - accuracy: 0.9519 - val_loss: 0.3327 - val_accuracy: 0.8833\n",
      "Epoch 88/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1408 - accuracy: 0.9423 - val_loss: 0.2693 - val_accuracy: 0.8889\n",
      "Epoch 89/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1370 - accuracy: 0.9303 - val_loss: 0.3202 - val_accuracy: 0.8944\n",
      "Epoch 90/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1120 - accuracy: 0.9540 - val_loss: 0.3168 - val_accuracy: 0.8667\n",
      "Epoch 91/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1508 - accuracy: 0.9231 - val_loss: 0.2698 - val_accuracy: 0.8722\n",
      "Epoch 92/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1375 - accuracy: 0.9519 - val_loss: 0.3006 - val_accuracy: 0.8667\n",
      "Epoch 93/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1444 - accuracy: 0.9443 - val_loss: 0.2847 - val_accuracy: 0.8556\n",
      "Epoch 94/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1320 - accuracy: 0.9399 - val_loss: 0.2923 - val_accuracy: 0.8667\n",
      "Epoch 95/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1512 - accuracy: 0.9351 - val_loss: 0.2655 - val_accuracy: 0.8778\n",
      "Epoch 96/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1177 - accuracy: 0.9591 - val_loss: 0.2914 - val_accuracy: 0.8833\n",
      "Epoch 97/100\n",
      "13/13 [==============================] - 33s 3s/step - loss: 0.1257 - accuracy: 0.9322 - val_loss: 0.2874 - val_accuracy: 0.8833\n",
      "Epoch 98/100\n",
      "13/13 [==============================] - 33s 3s/step - loss: 0.1323 - accuracy: 0.9467 - val_loss: 0.2953 - val_accuracy: 0.8889\n",
      "Epoch 99/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1350 - accuracy: 0.9370 - val_loss: 0.3057 - val_accuracy: 0.8722\n",
      "Epoch 100/100\n",
      "13/13 [==============================] - 34s 3s/step - loss: 0.1127 - accuracy: 0.9519 - val_loss: 0.3347 - val_accuracy: 0.8889\n"
     ]
    }
   ],
   "source": [
    "# define model\n",
    "history = model.fit_generator(\n",
    "      train_generator,\n",
    "      steps_per_epoch=13,\n",
    "      epochs=100,\n",
    "      validation_data=validation_generator,\n",
    "      validation_steps=9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d9dc8b61",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e20b31d6",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ee267bdf",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "cbdce7fb",
   "metadata": {},
   "outputs": [],
   "source": [
    "#save model\n",
    "model_json=model.to_json()\n",
    "with open(\"blanca_densenet_ada_relu.json\", \"w\") as json_file:\n",
    "    json_file.write(model_json)\n",
    "#serializar los pesos\n",
    "model.save_weights(\"blanca_densenet_ada_relu.h5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "b05790e8",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\oscar\\AppData\\Local\\Temp\\ipykernel_1280\\1979981568.py:1: UserWarning: `Model.predict_generator` is deprecated and will be removed in a future version. Please use `Model.predict`, which supports generators.\n",
      "  predictions=model.predict_generator(validation_generator, steps=len(validation_generator), verbose=1)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "9/9 [==============================] - 14s 1s/step\n"
     ]
    }
   ],
   "source": [
    "predictions=model.predict_generator(validation_generator, steps=len(validation_generator), verbose=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "30f61bd8",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "val_preds = np.round(predictions)# from probabilities to 0 or 1\n",
    "val_trues = validation_generator.classes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "id": "815d8a65",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\oscar\\AppData\\Local\\Temp\\ipykernel_1280\\2157498163.py:7: UserWarning: `Model.predict_generator` is deprecated and will be removed in a future version. Please use `Model.predict`, which supports generators.\n",
      "  Y_pred = model.predict_generator(validation_generator, num_of_test_samples // batch_size+1)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Confusion Matrix\n",
      "[[ 70   9  12]\n",
      " [ 13 123   0]\n",
      " [  5   0  45]]\n"
     ]
    }
   ],
   "source": [
    "#modify:\n",
    "from sklearn.metrics import confusion_matrix\n",
    "from sklearn.metrics import classification_report\n",
    "import numpy as np\n",
    "num_of_test_samples = 277 #number of testing samples\n",
    "batch_size=32 #batch size for the validation set\n",
    "Y_pred = model.predict_generator(validation_generator, num_of_test_samples // batch_size+1)\n",
    "y_pred = np.argmax(Y_pred, axis=1)\n",
    "print('Confusion Matrix')\n",
    "print(confusion_matrix(validation_generator.classes, y_pred))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "id": "fcd5652d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Classification Report\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "       hyena       0.80      0.77      0.78        91\n",
      "     leopard       0.93      0.90      0.92       136\n",
      "        wolf       0.79      0.90      0.84        50\n",
      "\n",
      "    accuracy                           0.86       277\n",
      "   macro avg       0.84      0.86      0.85       277\n",
      "weighted avg       0.86      0.86      0.86       277\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print('Classification Report')\n",
    "target_names = [ 'hyena', 'leopard', 'wolf']\n",
    "print(classification_report(validation_generator.classes, y_pred, target_names=target_names))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6f8f01c0",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ad6ed72d",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "34cbf1e7",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "id": "9e82b384",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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Izg4GDVr1sRrr72G3NxcAMCKFSswffp0HD58GDqdDjqdzpBny2qaI0eO4OGHH0ZQUBDCw8Px/PPP48aNG4b3Bw4ciO7du+Odd95BVFQUwsPDMWLECMO2bDl9+jS6deuGiIgIhISE4L777rMa/TU7Oxvjx49HTEwMAgICcM8992Dp0qWG93/77Td07doV5cqVQ2hoKFq3bo3Tp087PI4F4daD8koCPmmSiMhICODWLW22HRwM2HnWqpkyZcpgwIABWLFiBaZMmWJ4QOuGDRuQk5ODZ599Frdu3UJcXBxeeeUVlCtXDt988w369++PmjVr4oEHHnC6jfz8fPTo0QMVK1bEzz//jKysLLP2JYrQ0FCsWLECVapUwZEjR/Dcc88hNDQU48ePR+/evXH06FFs3brVEASEhYVZrePWrVt49NFH8eCDD2Lfvn24dOkShg4dipEjR5oFXDt27EBUVBR27NiBP/74A71790bTpk3x3HPP2dyHGzduoEuXLpg5cyYCAwPx8ccf4/HHH8fJkydRrVo1AMCAAQPw008/4d1330WTJk2QmpqKK1euAAAuXLiANm3aID4+Htu3b0e5cuXw448/Ii8vz+nxc5soBjIzMwUAkZmZ6ZH1bdwoRHS0EPLrJ6foaDmfiKg0uH37tjh27Ji4ffu2EEKIGzfMfxO9Od24oT7fx48fFwDE9u3bDfPatGkj+vTpY3eZLl26iHHjxhlet23bVowePdrwOjY2VsybN08IIcS3334rfH19xblz5wzvb9myRQAQmzZtsruN2bNni7i4OMPrqVOniiZNmlilM13Phx9+KO666y5xw+QAfPPNN8LHx0dkZGQIIYRISEgQsbGxIi8vz5DmqaeeEr1797abF1vq168v3nvvPSGEECdPnhQARHJyss20EydOFDVq1BA5OTmq1m15LplSe/0uddU0SUlAr17A+fPm8y9ckPOTkrTJFxEROVe3bl20bNkSy5YtAyCrJFJSUjB48GAAgF6vxxtvvIHGjRsjPDwcISEh+O6778weU+LI8ePHUa1aNURHRxvmtWjRwirdZ599hoceegiRkZEICQnBa6+9pnobpttq0qQJypYta5jXqlUr5Ofn4+TJk4Z5DRo0gK9J0X1UVBQuXbpkd703b97E+PHjUb9+fZQvXx4hISE4ceKEIX+HDh2Cr68v2rZta3P5Q4cO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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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mjVr0LVr18LYJRERERUTZteMPHz4EJcuXdI9jo2NRUxMDDw8PBAYGIiJEyfi+vXr+P777wHIIDJw4EB8+eWXeP7553Hz5k0AgJOTE9zd3S30MoiIiKi4Mrtm5OjRo2jYsCEaNmwIABg7diwaNmyou0w3ISEBcXFxuuW/+eYbpKWl4Z133oGvr69uGj16tIVeAhERERVnBRpnpLCYep0yERERFR1FdpwRIiIioqwYRoiIiEhRDCNERESkKIYRIiIiUhTDCBERESmKYYSIiIgUxTBCREREimIYISIiIkUxjBAREZGiGEaIiIhIUQwjREREpCiGESIiIlIUwwgREREpimGEiIiIFMUwQkRERIpiGCEiIiJFMYwQERGRohhGiIiISFEMI0RERKQohhEiIiJSFMMIERERKYphhIiIiBTFMEJERESKYhghIiIiRTGMEBERkaIYRoiIiEhRDCNERESkKIYRIiIiUhTDCBERESmKYYSIiIgUxTBCREREimIYISIiIkWZHUb27t2Lbt26wc/PDyqVCps3b85znT179qBRo0ZwdHRE5cqVsWTJkvyUlYiIiEogs8PIo0ePUL9+fXz99dcmLR8bG4suXbqgRYsWOHHiBD788EOMGjUKGzduNLuwREREVPLYmrtC586d0blzZ5OXX7JkCQIDAzF//nwAQM2aNXH06FF88cUXePnll83dPREREZUwVu8zcvDgQXTs2FFvXqdOnXD06FE8ffrU4DopKSlISkrSm4iIiKhksnoYuXnzJry9vfXmeXt7Iy0tDbdv3za4Tnh4ONzd3XVTQECAtYtJRERECimUq2lUKpXeYyGEwflaEydOhEaj0U3x8fFWLyMREREpw+w+I+by8fHBzZs39eYlJibC1tYWnp6eBtdxcHCAg4ODtYtGRERERYDVa0aaNGmCqKgovXk7duxAaGgo7OzsrL17IiIiKuLMDiMPHz5ETEwMYmJiAMhLd2NiYhAXFwdANrEMHDhQt/zw4cNx9epVjB07FufOncPy5cuxbNkyvPfee5Z5BURERFSsmd1Mc/ToUbRp00b3eOzYsQCAsLAwrFy5EgkJCbpgAgDBwcHYtm0b3n33XSxcuBB+fn5YsGABL+slIiIiAIBKaHuTFmFJSUlwd3eHRqOBm5ub0sUhIiIiE5h6/ua9aYiIiEhRDCNERESkKIYRIiIiUhTD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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "#PLOT\n",
    "acc = history.history['accuracy']\n",
    "val_acc = history.history['val_accuracy']\n",
    "loss = history.history['loss']\n",
    "val_loss = history.history['val_loss']\n",
    "\n",
    "epochs = range(len(acc))\n",
    "\n",
    "plt.plot(epochs, acc, 'bo', label='Training acc')\n",
    "plt.plot(epochs, val_acc, 'b', label='Validation acc')\n",
    "plt.title('Training and validation accuracy')\n",
    "plt.legend()\n",
    "\n",
    "plt.figure()\n",
    "\n",
    "plt.plot(epochs, loss, 'bo', label='Training loss')\n",
    "plt.plot(epochs, val_loss, 'b', label='Validation loss')\n",
    "plt.title('Training and validation loss')\n",
    "plt.legend()\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "77f7809c",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "40b275f2",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "id": "a93132bb",
   "metadata": {},
   "outputs": [],
   "source": [
    "#change working directory\n",
    "os.chdir('C:\\\\Users\\\\oscar\\\\Documents\\\\blanca')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1536eb31",
   "metadata": {},
   "outputs": [],
   "source": [
    "#ENSEMBLE LEARNING"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "id": "1a266eb4",
   "metadata": {},
   "outputs": [],
   "source": [
    "from keras.preprocessing import image\n",
    "import keras.backend as K\n",
    "import numpy as np\n",
    "import cv2\n",
    "import sys"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "id": "b399def3",
   "metadata": {},
   "outputs": [],
   "source": [
    "#cargar modelo:\n",
    "from keras.models import model_from_json\n",
    "# cargar json y crear el modelo\n",
    "json_file = open('blanca_resnet_ada_relu.json', 'r')\n",
    "loaded_model_json = json_file.read()\n",
    "json_file.close()\n",
    "model1 = model_from_json(loaded_model_json)#change sequentially\n",
    "# cargar pesos al nuevo modelo\n",
    "model1.load_weights(\"blanca_resnet_ada_relu.h5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "id": "f336fd20",
   "metadata": {},
   "outputs": [],
   "source": [
    "#cargar modelo:\n",
    "from keras.models import model_from_json\n",
    "# cargar json y crear el modelo\n",
    "json_file = open('blanca_vgg19_ada_swish.json', 'r')\n",
    "loaded_model_json = json_file.read()\n",
    "json_file.close()\n",
    "model2 = model_from_json(loaded_model_json)#change sequentially\n",
    "# cargar pesos al nuevo modelo\n",
    "model2.load_weights(\"blanca_vgg19_ada_swish.h5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "id": "b10d0f88",
   "metadata": {},
   "outputs": [],
   "source": [
    "#cargar modelo:\n",
    "from keras.models import model_from_json\n",
    "# cargar json y crear el modelo\n",
    "json_file = open('blanca_densenet_ada_swish.json', 'r')\n",
    "loaded_model_json = json_file.read()\n",
    "json_file.close()\n",
    "model3 = model_from_json(loaded_model_json)#change sequentially\n",
    "# cargar pesos al nuevo modelo\n",
    "model3.load_weights(\"blanca_densenet_ada_swish.h5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "id": "86b12a64",
   "metadata": {},
   "outputs": [],
   "source": [
    "members=[model1,model2,model3]#actualizar!!!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "id": "46a17b78",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Stacked Test Accuracy: 0.917\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn.metrics import accuracy_score\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.ensemble import ExtraTreesClassifier\n",
    "from sklearn.ensemble import GradientBoostingClassifier\n",
    "from sklearn.ensemble import AdaBoostClassifier\n",
    "from sklearn.ensemble import BaggingClassifier\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from keras.models import load_model\n",
    "from keras.utils import to_categorical\n",
    "from numpy import dstack\n",
    "\n",
    " \n",
    "# create stacked model input dataset as outputs from the ensemble\n",
    "def stacked_dataset(members, inputX):\n",
    "\tstackX = None\n",
    "\tfor model in members:\n",
    "\t\t# make prediction\n",
    "\t\tyhat = model.predict(inputX, verbose=0)\n",
    "\t\t# stack predictions into [rows, members, probabilities]\n",
    "\t\tif stackX is None:\n",
    "\t\t\tstackX = yhat\n",
    "\t\telse:\n",
    "\t\t\tstackX = dstack((stackX, yhat))\n",
    "\t# flatten predictions to [rows, members x probabilities]\n",
    "\tstackX = stackX.reshape((stackX.shape[0], stackX.shape[1]*stackX.shape[2]))\n",
    "\treturn stackX\n",
    " \n",
    "# fit a model based on the outputs from the ensemble members\n",
    "def fit_stacked_model(members, inputX, inputy):\n",
    "\t# create dataset using ensemble\n",
    "\tstackedX = stacked_dataset(members, inputX)\n",
    "\t# fit standalone model\n",
    "\t#model = LogisticRegression()#\n",
    "\tmodel = RandomForestClassifier(n_estimators=100, max_depth=None,max_features=20,min_samples_split=2, random_state=0)# n_estimators=n of trees\n",
    "\t#model = ExtraTreesClassifier()\n",
    "\t#model = GradientBoostingClassifier()\n",
    "\t#model = AdaBoostClassifier(n_estimators=100)\n",
    "\t#model = BaggingClassifier(KNeighborsClassifier(),max_samples=0.5, max_features=0.5)\n",
    "\tmodel.fit(stackedX, inputy)\n",
    "\treturn model\n",
    " \n",
    "# make a prediction with the stacked model\n",
    "def stacked_prediction(members, model, inputX):\n",
    "\t# create dataset using ensemble\n",
    "\tstackedX = stacked_dataset(members, inputX)\n",
    "\t# make a prediction\n",
    "\tyhat = model.predict(stackedX)\n",
    "\treturn yhat\n",
    " \n",
    "\n",
    "# fit stacked model using the ensemble\n",
    "model = fit_stacked_model(members, x_train, y_train)\n",
    "# evaluate model on test set\n",
    "yhat = stacked_prediction(members, model, x_test)\n",
    "acc = accuracy_score(y_test, yhat)\n",
    "print('Stacked Test Accuracy: %.3f' % acc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 136,
   "id": "historical-forth",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pickle\n",
    "\n",
    "filename = \"stacked_model.pickle\"\n",
    "\n",
    "# save model\n",
    "pickle.dump(model, open(filename, \"wb\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "id": "soviet-breed",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "       hyena       0.92      0.85      0.88        91\n",
      "     leopard       0.92      0.94      0.93       136\n",
      "        wolf       0.94      0.98      0.96        50\n",
      "\n",
      "   micro avg       0.92      0.92      0.92       277\n",
      "   macro avg       0.93      0.92      0.92       277\n",
      "weighted avg       0.92      0.92      0.92       277\n",
      " samples avg       0.92      0.92      0.92       277\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\oscar\\anaconda3\\Lib\\site-packages\\sklearn\\metrics\\_classification.py:1469: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in samples with no predicted labels. Use `zero_division` parameter to control this behavior.\n",
      "  _warn_prf(average, modifier, msg_start, len(result))\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import classification_report\n",
    "vp=np.round(yhat)\n",
    "vt=y_test\n",
    "target_names = [ 'hyena','leopard', 'wolf']\n",
    "print(classification_report(vt,vp,target_names=target_names))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "orange-surgery",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 153,
   "id": "9025e99b",
   "metadata": {},
   "outputs": [],
   "source": [
    "#loads image to be classified. Activate libraries\n",
    "\n",
    "from tensorflow.keras.preprocessing import image\n",
    "import keras.backend as K\n",
    "import numpy as np\n",
    "import cv2\n",
    "import sys"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 321,
   "id": "877a33c8",
   "metadata": {},
   "outputs": [],
   "source": [
    "#load image:\n",
    "#from tensorflow.keras.applications.densenet import preprocess_input\n",
    "img_path = \"C:\\\\Users\\\\oscar\\\\Documents\\\\blanca\\\\tritons\\\\Tr28.bmp\"\n",
    "\n",
    "img = image.load_img(img_path, target_size=(250, 200))\n",
    "x = image.img_to_array(img)\n",
    "x = np.expand_dims(x, axis=0)\n",
    "x /= 255\n",
    "#x = preprocess_input(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 322,
   "id": "7c1f99f2",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0. 1. 0.]]\n"
     ]
    }
   ],
   "source": [
    "xxx = stacked_prediction(members, model, x)\n",
    "print(xxx)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 261,
   "id": "8eaf8243",
   "metadata": {},
   "outputs": [],
   "source": [
    "#load image for RESNET classification:\n",
    "from tensorflow.keras.applications.resnet50 import preprocess_input\n",
    "img_path = \"C:\\\\Users\\\\oscar\\\\Documents\\\\blanca\\\\tritons\\\\Tr46.bmp\"\n",
    "\n",
    "img = image.load_img(img_path, target_size=(250, 200))\n",
    "x = image.img_to_array(img)\n",
    "x = np.expand_dims(x, axis=0)\n",
    "#x /= 255\n",
    "x = preprocess_input(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 262,
   "id": "2349d5bb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1/1 [==============================] - 0s 173ms/step\n",
      "[[1.2856571e-04 9.9987102e-01 3.9980588e-07]]\n"
     ]
    }
   ],
   "source": [
    "p = model1.predict(x)\n",
    "print(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 357,
   "id": "2c042648",
   "metadata": {},
   "outputs": [],
   "source": [
    "#load image for VGG19 classification:\n",
    "from tensorflow.keras.applications.vgg19 import preprocess_input\n",
    "img_path = \"C:\\\\Users\\\\oscar\\\\Documents\\\\blanca\\\\tritons\\\\Tr46.bmp\"\n",
    "\n",
    "img = image.load_img(img_path, target_size=(250, 200))\n",
    "x = image.img_to_array(img)\n",
    "x = np.expand_dims(x, axis=0)\n",
    "#x /= 255\n",
    "x = preprocess_input(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 358,
   "id": "b6a74f9b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1/1 [==============================] - 0s 171ms/step\n",
      "[[1.0711788e-02 9.8928738e-01 8.4714543e-07]]\n"
     ]
    }
   ],
   "source": [
    "p = model2.predict(x)\n",
    "print(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 450,
   "id": "4b7cc428",
   "metadata": {},
   "outputs": [],
   "source": [
    "#load image for DENSENET classification:\n",
    "from tensorflow.keras.applications.densenet import preprocess_input\n",
    "img_path = \"C:\\\\Users\\\\oscar\\\\Documents\\\\blanca\\\\tritons\\\\Tr46.bmp\"\n",
    "\n",
    "img = image.load_img(img_path, target_size=(250, 200))\n",
    "x = image.img_to_array(img)\n",
    "x = np.expand_dims(x, axis=0)\n",
    "#x /= 255\n",
    "x = preprocess_input(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 451,
   "id": "cfe13c2a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1/1 [==============================] - 0s 361ms/step\n",
      "[[9.4830319e-03 9.8987269e-01 6.4430764e-04]]\n"
     ]
    }
   ],
   "source": [
    "p = model3.predict(x)\n",
    "print(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "convinced-infrastructure",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cathedral-maker",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
